home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / KmdOps / kmdCode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-30  |  39.3 KB  |  1,496 lines

  1. /*
  2.  * C O P Y R I G H T   N O T I C E :
  3.  * Copyright 1986 Eric Jul.  May not be used for any
  4.  * purpose without written permission from the author.
  5.  *
  6.  * File: /usr/Em/Kernel/KmdOps/kmdCode.c  Origin: Eric Jul, 1986-05-01
  7.  * Note: Rewritten for TCP/IP, May 1986.
  8.  *
  9.  * This file contain the bulk of the procedures to handle the kmd stuff
  10.  * Log:    84/07/13 fixed bug in KMDShip re. the type of fArgs. Eric Jul
  11.  *
  12.  * Note: 84/11/29  19:04:23  schwartz
  13.  * Changed all calls to malloc so they don't call HoldSigs and ReleaseSigs
  14.  * before and after, since this is now done in (Almeses version of) malloc.
  15.  *
  16.  * 85/02/27 eric
  17.  * Added GetBlocks and fixed trace sockets on socket death.
  18.  * NOTE:  The data structure rooted in THeads and nextHead must
  19.  * be updated with signals held.
  20.  * Added stuff so that KMD may be stuffed into Ejects too.
  21.  *
  22.  * 86/05/02 eric
  23.  * Most Eden considerations removed.
  24.  *
  25.  * 88/07/05 cjeffery
  26.  * BSD support moved under xkernel simulator
  27.  */
  28.  
  29. #undef integer
  30. #include "Kernel/h/system.h"
  31. #include "Kernel/h/expandArray.h"
  32. #include <nlist.h>
  33. extern errno;  /* IPC status if call returns -1; NB: not set upon success!*/
  34.  
  35. extern int
  36.   DisplayEdenMsg(),
  37.   GetEdenMsg(),
  38.   PutEdenMsg();
  39.  
  40. extern char progArg0Name[];
  41.  
  42. #ifdef xkernel
  43. #include "userupi.h"
  44. #include "userprocess.h"
  45. #include "debug.h"
  46. #include "ip.h"
  47. #include "tcp.h"
  48. static IPaddr myipaddr;
  49. #endif
  50.  
  51. #include "Kernel/h/mmTypes.h"
  52. #include "Kernel/h/mmCodes.h"
  53. #include "Kernel/h/unixCodes.h"
  54. #include "Kernel/h/mmBufTypes.h"
  55. #include "Kernel/h/mmFifoTypes.h"
  56. #include "Kernel/h/mmMsgDefs.h"
  57. #include "Kernel/h/mmMsgTypes.h"
  58. #include "Kernel/h/kEvents.h"
  59. #include "Kernel/h/kmdDefs.h"
  60. #include "Kernel/h/kmdTypes.h"
  61. #include "Kernel/h/timerTypes.h"
  62. #include "Kernel/h/sigio.h"
  63. #include "Kernel/h/map.h"
  64.  
  65. /* this is defined in emTypes.h which includes <a.out.h> which defines a struct nlist,
  66.  * which is incompatible with the one defined above in <nlist.h>.
  67.  */
  68. #include "Kernel/h/emstream.h"
  69.  
  70. #ifndef xkernel
  71. #include <errno.h>
  72. #include <sys/file.h>
  73. #include <sys/ioctl.h>
  74. #endif
  75. #ifdef xkernel
  76. extern Map tcp2emsessn;
  77. #endif
  78. extern int DebugLevel, MMTrace, emTracing;
  79.  
  80. /* forward */
  81. HResult KMDMsgHandler();
  82. void KMDStartTrace();
  83. void KMDShip();
  84. int  KMDRequestSignal();    /* fwrd. decl. of signal handler */
  85. void KMDCleanSock();
  86.  
  87.  
  88. /* Tables: */
  89.  
  90. /* Table sizes */
  91. #define  MAXSNAPS     64
  92. #define  MAXTRACES    64
  93. #define  MAXVARS     512
  94. #define  MAXREQSOCKS  10          /* Each uses a file descriptor */
  95.  
  96. typedef char *charPtr;
  97.  
  98. typedef struct SnapElement
  99. {
  100.     char   *name;
  101.     HandlerPtr handler;
  102. } SnapElement, *SnapElemPtr;
  103.  
  104. #ifdef xkernel
  105. extern struct DebugInfo *debugStart();
  106. #endif xkernel
  107.  
  108. typedef struct TraceElem
  109. {
  110.     struct TraceElem *next;      /* Ptr to next trace destination */
  111.     int             tracesock;   /* Destination sock */
  112.     struct DebugInfo *debugger;
  113.     int             level;       /* Output level indicator */
  114. } TraceElem, *TraceElemPtr;
  115.  
  116. typedef struct TraceHead
  117. {
  118.     char            *name;
  119.     TraceElemPtr    first;
  120. } TraceHead, TraceHeadPtr;
  121.  
  122. typedef struct VarElem
  123. {
  124.     char            *name;
  125.     int             *addr;
  126. } VarElem, VarElemPtr;
  127.  
  128.  
  129. typedef struct PreparedElem {
  130.     char            *name;
  131.     int              level;
  132. } PreparedElem, *PreparedElemPtr;
  133.  
  134.  
  135.  
  136. /*** table stuff ***/
  137. SnapElement         Snaps[MAXSNAPS];
  138. TraceHead           THeads[MAXTRACES];
  139. VarElem             Vars[MAXVARS];
  140.  
  141. #ifndef xkernel
  142. int                 ReqSocks[MAXREQSOCKS];
  143. #endif
  144.  
  145. PreparedElem       *PreparedTraces;
  146.  
  147. /* ... and the next free element for them.
  148.  * (Linear search is fine with me.)
  149.  */
  150. int nextSnap = 0;
  151. int nextHead = 0;
  152. int nextVar  = 0;
  153. int nextReq  = 0;
  154. int nextPrepared = 0;
  155.  
  156. /*** End of Table stuff ***/
  157.  
  158.  
  159.  
  160.  
  161.  
  162. int KMDTraceAct = 0;    /* Number of active traces */
  163. int anyKMDTrace = 1;    /* True if any KMD tracing */
  164. int anyKMD      = 1;    /* True if any tracing is possible:
  165.                            False means no tracing at all */
  166. #ifdef xkernel
  167. PROTL KMDProtl;
  168. #else
  169. int KMDRequestSock;   /* Socket for rec. requests */
  170. #endif
  171. int KMDSnapSock;      /* Current Snapshot socket */
  172. int reqSrcLength;
  173. #ifdef BSD
  174. struct sockaddr_in  reqSrc;   /* Source address of request */
  175. struct sockaddr_in
  176.   mySocket = {AF_INET};       /* KMD Socket for requests */
  177. #endif
  178.  
  179. int interruptScheduled = 0;
  180.  
  181. #define KMDTICKSIZE 300 /* milliseconds */
  182. int vKMDTickSize = KMDTICKSIZE; /* milliseconds */
  183.  
  184. #define NULLSOCK   0
  185. #define KMDSIG     SIGURG
  186. #define KMDSIGPIPE SIGPIPE
  187.  
  188. /*** End of var decl. ***/
  189.  
  190. #define endcase break
  191.  
  192. #define DoArgs(stx, fFmt, fArgs) \
  193. { \
  194.     struct _iobuf _strbuf; \
  195.     char fullfmt[2000]; \
  196.  \
  197.     _strbuf._flag = _IOWRT+_IOSTRG; \
  198.     _strbuf._ptr = stx; \
  199.     _strbuf._cnt = 32767; \
  200.     sprintf(fullfmt, "Em%02x: ",GetLNN()); \
  201.     (void) strcat(fullfmt, fFmt); \
  202.     _doprnt(fullfmt, fArgs, &_strbuf); \
  203.     putc('\0',&_strbuf); \
  204.     if (KMDTest) printf(" ... DidArgs: %s\n", stx); \
  205. }
  206.  
  207. #ifdef xkernel
  208. /*
  209.  *  XKERNEL HANDLERS
  210.  *
  211.  * see note in .../FileLoad/loadCode.c for an explanation of xkernel handlers
  212.  * implementing tcp connections.  It appears the behavior of Kmd connections
  213.  * may warrant a somewhat simpler approach than for loadCode.
  214.  */
  215. KMDdemux_handler(s,msg,len)
  216. SESSN s;
  217. register char *msg;
  218. int len;
  219. {
  220.   register EMSTREAM *ems;
  221.  
  222.   xkhandlerstart();
  223.   if (KMDTest)
  224.     printf("In KMDdemux_handler, session 0x%x, msg %s, len %d\n", s, msg, len);
  225.   ems = (EMSTREAM *)Map_Lookup(tcp2emsessn, (int)s);
  226.   if(ems==(EMSTREAM *)0x80000000) {/*include some file for IsNIL definition*/
  227.     if (KMDTest) printf("no EMSTREAM found in KMDdemux_handler!\n");
  228.     xkhandlerend();
  229.     return;
  230.   }
  231.   ems->eof = !len;
  232.   INSERTMSGQUEUE(ems->buffers,msg,len);
  233.   if (xsemcount(ems->sem) >= 0) {
  234.     if (KMDTest) printf("No one waiting for data on %#x\n", s);
  235.   }
  236.   xkv(ems->sem);
  237.  
  238.   if (!ems->usedForDebugging) {
  239.     HoldSigs();
  240.     QueueTask((HandlerPtr)KMDMsgHandler, (char *)ems);
  241.     ReleaseSigs();
  242.   }
  243.   xkhandlerend();
  244. }
  245.  
  246. KMDopendone_handler(s)
  247. SESSN s;
  248. {
  249.   register EMSTREAM *ems;
  250.  
  251.   xkhandlerstart();
  252.   if (KMDTest) printf("In KMDopendone_handler, session 0x%x\n", s);
  253.   /* create emstream things */
  254.   if(!(ems=(EMSTREAM *)malloc(sizeof(EMSTREAM)))) {
  255.     if (KMDTest) printf("malloc #1 fails in FLopendone_handler!\n");
  256.     xkhandlerend();
  257.     return -1;
  258.   }
  259.   ems->sessn = s;
  260.   ems->sem = xcreatesemaphore(0);
  261.   ems->eof = 0;
  262.   ems->usedForDebugging = 0;
  263.   if((ems->buffers = (msgqueue *)malloc(sizeof(msgqueue)))==NULL){}
  264.   ems->buffers->next = ems->buffers->prev = ems->buffers;
  265.  
  266.   /* one ring to rule them all, and in the darkness bind them. */
  267.   Map_Insert(tcp2emsessn, (int)s, (int)ems);
  268.  
  269.   /* Tell the new socket that it has been connected */
  270.   if (KMDTest )
  271.     printf("In KMDopendone_handler, shipping reply from ems 0x%x\n", ems);
  272.  
  273.   KMDShip((int)ems, "KMDConnected to host %d\n", GetLNN());
  274.   xkhandlerend();
  275.   return 0;
  276. }
  277.  
  278. KMDclosedone_handler(s)
  279. SESSN s;
  280. {
  281.   register EMSTREAM *ems;
  282.  
  283.   xkhandlerstart();
  284.   ems = (EMSTREAM *)Map_Lookup(tcp2emsessn, (int)s);
  285.   KMDTrace("UserIO", 3, "'Socket' (tcp 0x%x) (ems 0x%x) died.\n", s, ems);
  286.   xkhandlerend();
  287. }
  288.  
  289. #endif
  290.  
  291.  
  292.  
  293. /* Set the KMD flags.  Used for dynamically changing the values of
  294.  *  trace flags
  295.  *
  296.  * Problem: In the MM there are statements of the form:
  297.  *  if (MMTrace > 7) ... which circumvent calling MMTraceMsg thus
  298.  *  resulting in less output than desired.
  299.  *  There are also statements like: if (MMTrace) MMTraceMsg ...
  300.  *  (see MMTraceMxg macro in some .h file), but the hack below solved that
  301.  */
  302. void KMDSetFlags()
  303. {
  304.   anyKMDTrace = KMDTraceAct != 0;
  305.   if (anyKMDTrace && (! MMTrace)) MMTrace = -1; /* Hack */
  306.   if (! anyKMDTrace && (MMTrace < 0 )) MMTrace = 0;/* Hack */
  307.   anyKMD = DebugLevel || MMTrace || KMDTraceAct;
  308.   if (KMDTest)
  309.     printf(" ... any=%d, TraceAct=%d, anyKMDTrace=%d, -x%d, -t%d\n",
  310.        anyKMD, KMDTraceAct, anyKMDTrace, DebugLevel, MMTrace);
  311. }
  312.  
  313.  
  314. /* Just a front end for malloc to handle:
  315.    1)   Disable-enable of signals.
  316.    2)   Errors.
  317. */
  318. charPtr kmdalloc(memsize)
  319. int memsize;
  320. {
  321.   charPtr i;
  322.  
  323.   if ( ! (i = (charPtr) malloc((unsigned)memsize) ) ) {
  324.     printf("\n*** KMD fatal error malloc returned NULL - dumping core\n");
  325.     abort();
  326.   }
  327.   return(i);
  328. }
  329.  
  330. /* Must be very careful:  This code segment must be protected
  331.  * from signals, but signals may or may not already be held.
  332.  * The problem is that deallocation may be required DURING trace output
  333.  * for signal handlers.
  334.  * EXTREME CAUTION necessary.
  335.  * 85/02/27:  Lastest fix avoids kmdfree during trace output if sigs are held.
  336.  *            by employing KMDDeadPipe and KMDCleanSock.
  337.  *            This basically make the above caution unnecessary.
  338.  */
  339. void kmdfree(fPtr)
  340. TraceElemPtr fPtr;
  341. {
  342.   if (KMDTest) printf(" ... kmdfree, %s\n", SigsHeld ? "SigsHeld!!!":
  343.               "Sigs fortunately not held");
  344.   if (SigsHeld) return; /* Lose it!*/
  345.   free((char *)fPtr);
  346. }
  347.  
  348. /************************************************************************/
  349.  
  350.  
  351. #ifdef BSD
  352.  
  353. /*ARGSUSED*/
  354. int SIGIOOccurred(fKind, fSock)
  355. int fSock;
  356. {
  357.   QueueTask(KMDMsgHandler, (char *) fSock);
  358.   return 0; /* procedure ought to be void */
  359. }
  360.  
  361. #endif
  362.  
  363. /************************************************************************/
  364.  
  365.  
  366. /* Encodes a KMD msg according to the fFmt and the fArgs and Sends it
  367.  * to the specified socket.
  368.  */
  369. /* VARARGS2 */
  370. void KMDShip(fSock, fFmt, fArgs)
  371. int   fSock;             /* Sock to ship to */
  372. char *fFmt;              /* Format pointer for printf */
  373. char *fArgs;             /* Argument pointer for printf */
  374. {
  375.   struct _iobuf _strbuf;
  376.   char str[2000];
  377.   char fullfmt[132];
  378.   KKStatus status;
  379.  
  380.   if(fSock == NULLSOCK) return;
  381.   _strbuf._flag = _IOWRT+_IOSTRG;
  382. #ifdef vax
  383.   _strbuf._ptr = str;
  384. #else
  385.   _strbuf._ptr = (unsigned char *)str;
  386. #endif
  387.  
  388.   _strbuf._cnt = 32767;
  389.   sprintf(fullfmt, "Em%02x: ",GetLNN());
  390.   (void) strcat(fullfmt,fFmt);
  391.   _doprnt(fullfmt, &fArgs, &_strbuf);
  392.   putc('\0',&_strbuf);
  393.   if (KMDTest)
  394.     printf(" ... shipping to %d: %s\n", fSock, str);
  395. #ifndef xkernel
  396.   if (KMDSTDOUTSOCK == fSock) {
  397.     printf("%s", str);
  398.     (void) fflush(stdout);
  399.     return;
  400.   }
  401. #endif
  402.   status = KMDSend(fSock, KMDCDATA, 0, str);
  403.   if (!mSUCCESS(status)) {
  404.     if (KMDTest) perror("KMDSend");
  405. #ifdef BSD
  406.     (void) close(fSock);
  407. #else
  408. #ifdef xkernel
  409.     ems_close((EMSTREAM *)fSock);
  410. #endif
  411. #endif
  412.   }
  413.   return;
  414. }
  415.  
  416.  
  417. /* Sends a snapshot line to the current snapshot socket */
  418. /*VARARGS1*/
  419. void KMDPrint(fFmt, fArgs)
  420. char *fFmt, *fArgs;       /* Args as for DebugMsg */
  421. {
  422.   struct _iobuf _strbuf;
  423.   char str[2000];
  424.   KKStatus status;
  425.  
  426.   if (KMDTest) printf("KMDPrint called Snapsocket = %d\n", KMDSnapSock);
  427.   if (KMDSnapSock == NULLSOCK) return;
  428.   _strbuf._flag = _IOWRT+_IOSTRG;
  429. #ifdef vax
  430.   _strbuf._ptr = str;
  431. #else
  432.   _strbuf._ptr = (unsigned char *)str;
  433. #endif
  434.   _strbuf._cnt = 32767;
  435.  
  436.   _doprnt(fFmt, &fArgs, &_strbuf);
  437.   putc('\0',&_strbuf);
  438.   if (KMDTest) printf(" ... snap shipping to %d:%s\n", KMDSnapSock, str);
  439. #ifndef xkernel
  440.   if (KMDSTDOUTSOCK == KMDSnapSock) {
  441.     printf("%s", str);
  442.     (void) fflush(stdout);
  443.     return;
  444.   }
  445. #endif
  446.   status = KMDSend(KMDSnapSock, KMDCDATA, 0, str);
  447.   if (!mSUCCESS(status)) {
  448.     perror("KMDSend");
  449. #ifdef BSD
  450.     (void) close(KMDSnapSock);
  451. #else
  452. #ifdef xkernel
  453.     ems_close((EMSTREAM *)KMDSnapSock);
  454. #endif
  455. #endif
  456.     KMDSnapSock = NULLSOCK;
  457.   }
  458.   return;
  459. }
  460.  
  461. /************************************************************************/
  462.  
  463. void  KMDSetSnap1(fName, fHandler)
  464. char                *fName;             /* The Name of the snapshot */
  465. HandlerPtr          fHandler;           /* The snapshot handler.     */
  466. {
  467.   register int        i;
  468.   if (KMDTest) printf("KMDSetSnap1 for %s\n", fName);
  469.   for (i=0; i < nextSnap ? strcmp(fName, Snaps[i].name) : 0; i++);
  470.   if (KMDTest) printf(" ... i=%d, nextSnap = %d\n", i, nextSnap);
  471.   if (i == nextSnap) { /* A new one */
  472.     nextSnap++;
  473.     if (Snaps[i].name = kmdalloc(strlen(fName) +1))
  474.       (void) strcpy(Snaps[i].name, fName);
  475.   } else {
  476.     /* An existing one */
  477.   }
  478.   Snaps[i].handler = fHandler;
  479. }
  480.  
  481.  
  482. void KMDSetTrace1(fName)
  483. char *fName;                 /* The name of the trace */
  484. {
  485.   register int i;
  486.  
  487.   if (KMDTest) printf("KMDSetTrace1 for %s\n", fName);
  488.   for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
  489.   if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
  490.   if (i < nextHead) {
  491.     /* An existing one */
  492.     if (KMDTest)
  493.       printf("KMDSetTrace: Duplicate Trace definition ignored , name: %s\n",
  494.          fName);
  495.     return;
  496.   }
  497.  
  498.   /* A new one */
  499.   if (THeads[i].name = kmdalloc(strlen(fName) +1) ) {
  500.     (void) strcpy(THeads[i].name, fName);
  501.   } else {
  502.     printf("Malloc returned 0\n");
  503.   }
  504.   THeads[i].first = NULL;
  505.   nextHead++;
  506.  
  507.   /* Check to see if a trace request was made earlier for this trace */
  508.   for (i=0; i<nextPrepared ? strcmp(fName, PreparedTraces[i].name): 0; i++);
  509.   if (i < nextPrepared) {
  510.     /* A trace request was done earlier, so start it now that the
  511.        trace has been defined */
  512.     KMDStartTrace(fName, PreparedTraces[i].level, KMDSTDOUTSOCK, TRUE);
  513.   }
  514. }
  515.  
  516.  
  517. /* Lookup the named variable first in the table and if not found then
  518.  * try nlist().  If found there then cache in table.
  519.  * If not found at all then return -1
  520.  */
  521. int *NlistValueOf(fName)
  522. char *fName;
  523. {
  524.   register int        i;
  525.   static struct nlist nl[] = {
  526.     { 0 },
  527.     { 0 }
  528.   };
  529.   char vName[132];
  530.   int *ptr;
  531.   VarElem     tempVarElem;
  532.  
  533.   if ( KMDTest ) printf(" ... VarLookup of %s\n", fName);
  534.   for (i=0; i < nextVar ? strcmp(fName, Vars[i].name) : 0; i++);
  535.   if (KMDTest) printf(" ... i = %d, nextVar = %d\n", i, nextVar);
  536.   if (i < nextVar) {
  537.     /* An existing one */
  538.     /* For performance: reorganize list, use move-to-front */
  539.     tempVarElem = Vars[i];
  540.     Vars[i] = Vars[0];
  541.     Vars[0] = tempVarElem;
  542.     return((int*) Vars[0].addr );
  543.   }
  544.     
  545.   /* Try looking it up using nlist */
  546.  
  547.   if ( KMDTest ) printf(" ... trying nlist of file %s\n", progArg0Name);
  548.   (void) strcpy(&vName[0], fName);
  549.   nl[0].n_name = vName;
  550. #ifdef BSD /* make this xsimul if you must */
  551.   nlist(progArg0Name, nl);   /* progArg0Name set in main.c */
  552. #else
  553.   nl[0].n_type = 0;          /* no unix->no nlist: force a failure */
  554. #endif
  555.   if ( nl[0].n_type == 0 ) { /* Not there or nlist failed */
  556.     if ( KMDTest )
  557.       printf(">> Warning: nlist failed for %s, file %s.\n",fName,progArg0Name);
  558.     ptr = (int *) -1;
  559.   } else {
  560.     ptr = (int *) nl[0].n_value;
  561.     if (KMDTest) 
  562.       printf(" ... nlist returned addr 0x%08x  value %d (0%x)\n",
  563.          ptr, *ptr, *ptr);
  564.   }
  565.     
  566.   /* Cache it in table */
  567.   if ( nextVar >= MAXVARS ) { /* Table full */
  568.     if (nextVar++ == MAXVARS)
  569.       /* Print warning once only */
  570.       printf(">> Warning: KMD Vars table size of %d too small.\n", MAXVARS);
  571.     return((int *) ptr);
  572.   }
  573.  
  574.   i = nextVar++;
  575.   if ( (Vars[i].name = kmdalloc(strlen(fName) +1)) )
  576.     (void) strcpy(Vars[i].name, fName);
  577.   Vars[i].addr = ptr;
  578.   if (KMDTest) printf(" ... name %s, addr 0x%08x, value %d\n",
  579.               Vars[i].name, ptr, (ptr == ((int *) -1) ? -1 : *ptr) );
  580.   return((int*) ptr);
  581. }
  582.     
  583. /* Looks up the C-language variable named as given in fName.
  584.  * Note, a leading _ is added since cc does this too
  585.  */
  586. int *VarLookup(fName)
  587. char *fName;
  588. {
  589.   char buf[200];
  590.   (void) strcpy(buf, "_");
  591.   (void) strcat(&buf[1], fName);
  592.   return((int *) NlistValueOf(buf));
  593. }
  594.  
  595.  
  596. void  KMDSetVar1(fName, fAddr)
  597. char                *fName;             /* The Name of the Variable */
  598. int                 *fAddr;             /* The address of the Variable */
  599. {
  600.   register int        i;
  601.   char                buf[200];
  602.   (void) strcpy(buf, "_");
  603.   (void) strcat(&buf[1], fName);
  604.   if (KMDTest) printf("KMDSetVar1 for %s, addr = 0x%0x8\n", buf, fAddr);
  605.   for (i=0; i < nextVar ? strcmp(buf, Vars[i].name) : 0; i++);
  606.   if (KMDTest) printf(" ... i = %d, nextVar = %d\n", i, nextVar);
  607.   if (i == nextVar) {  /* A new one */
  608.     nextVar++;
  609.   } else {
  610.     /* An existing one */
  611.     if ((Vars[i].addr) == fAddr) return;
  612.     printf("KMDSetVar: Duplicate Var name: %s - second call ignored.\n", buf);
  613.     return;
  614.   }
  615.   if ((Vars[i].name = kmdalloc(strlen(buf) +1)) )
  616.     (void) strcpy(Vars[i].name, buf);
  617.   Vars[i].addr = fAddr;
  618.   if (KMDTest) printf(" ... name %s, addr 0x%08x, value %d\n",
  619.               Vars[i].name, Vars[i].addr, *(Vars[i].addr) );
  620. }
  621.  
  622.  
  623.  
  624. /* Due to parameters to _doprnt KMDTracex1 should not be called directly
  625.  * unless you know what you are doing.
  626.  * KMDTrace1  may be called directly with variable args.
  627.  * KMDTracex1 must be called "indirectly" with 4 args.
  628.  * Both should be called using the macros KMDTrace and KMDTracex resp.
  629.  */
  630.  
  631. /*VARARGS3*/
  632. void KMDTrace1(fName, fLevel, fFmt, fArgs)
  633. char *fName;         /* Trace name */
  634. int   fLevel;        /* The level at which output is to be done.*/
  635. char *fFmt, *fArgs;  /* For _doprnt */
  636. {
  637.   KMDTracex1(fName, fLevel, fFmt, &fArgs);
  638. }
  639.  
  640. /*VARARGS3*/
  641. void KMDTracex1(fName, fLevel, fFmt, fArgs)
  642. char *fName;         /* Trace name */
  643. int   fLevel;        /* The level at which output is to be done.*/
  644. char *fFmt, *fArgs;  /* For _doprnt */
  645. {
  646.   register int i;
  647.   register TraceElemPtr p, q;
  648.   char str[2000];
  649.   int notEncoded;
  650.  
  651.   if (KMDTest)
  652.     printf("  KMDTrace1: fName = %s, fLevel = %d\n", fName, fLevel);
  653.   KMDSetFlags();
  654.   if (!anyKMDTrace) return;
  655.   for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
  656.   if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
  657.  
  658.   if (i == nextHead) {
  659.     if (KMDTest) printf(" ... not found - ignored.\n");
  660.     return;
  661.   }
  662.  
  663.   notEncoded = 1;   /* True, until the string to print has been encoded */
  664.   for (p = THeads[i].first, q = NULL; p != NULL; ) {
  665.     if (KMDTest)
  666.       printf(" ... q = 0x%08x, p = 0x%08x, sock = %d, level = %d\n",
  667.          q, p, p->tracesock, p->level);
  668.     if ((fLevel > p->level) || (p->tracesock==NULLSOCK))  {
  669.       /* Skip it */
  670.       q = p; p = p-> next;            
  671.     } else { /* send trace data to this listner */
  672.       if (KMDTest) printf(" ... found a trace listner ..\n");
  673.       if (notEncoded) {
  674.     notEncoded = 0;
  675. #ifdef vax
  676.     DoArgs(str, fFmt, fArgs);   /* Encode them args! */
  677. #else
  678.     DoArgs((unsigned char *)str, fFmt, fArgs);   /* Encode them args! */
  679. #endif
  680.  
  681.       }
  682. #ifdef xkernel
  683.       if (p->debugger) {
  684.     runDebugger(p, str);
  685.     q=p; p = p->next;
  686.       } else {
  687. #else
  688.       {
  689. #endif xkernel
  690.     if ( mSUCCESS(KMDSend(p->tracesock, KMDCDATA, 0, str)) ) {
  691.       /* Send ok, advance pointer */
  692.       q=p; p = p->next;
  693.     } else {
  694.       /* Unsuccessful send: There is a problem here.
  695.        * We would like to remove the entry from the list,
  696.        * but we may be in the middle of an interrupt, or
  697.        * get one.
  698.        * Therefore, we will just null the
  699.        * socket and the trace entry will eventually
  700.        * be cleaned when its file descriptor is reused
  701.        */
  702.       if ( KMDTest )
  703.         printf(" ... Bum Sock = %d\n", p->tracesock);
  704.       p->tracesock = NULLSOCK;
  705.       q=p; p = p->next;
  706.     }
  707.       }
  708.     }
  709.   }
  710. }
  711.  
  712.  
  713. /********************************************************************/
  714. /*      KMD defined snapshots:                                      */
  715. /*          Snapshots   Print the possible snapshots.               */
  716. /*          Traces      Print the possible traces.                  */
  717. /*          Variables   Print the currently accessible vars.        */
  718. /*          Flush       Flushes stderr and stdout.                  */
  719. /*          Menu        Print a menu.                               */
  720. /*          NOP         A NOP                                       */
  721. /********************************************************************/
  722.  
  723. /* Snapshot */
  724. /* VARARGS */
  725. static void Snapshots()
  726. /* Print the snapshots available */
  727. {
  728.   register int i;
  729.     
  730.   KMDPrint("The following %d snapshots are available:\n", nextSnap);
  731.  
  732.   for (i=0; i < nextSnap; i += 4)
  733.     KMDPrint("  %-18.18s  %-18.18s  %-18.18s  %.18s\n", Snaps[i].name,
  734.          (i+1 < nextSnap) ? Snaps[i+1].name : " ",
  735.          (i+2 < nextSnap) ? Snaps[i+2].name : " ",
  736.          (i+3 < nextSnap) ? Snaps[i+3].name : " ");
  737. }
  738.  
  739.  
  740. /* Snapshot */
  741. /*VARARGS*/
  742. static void Traces()
  743. /* Print the traces available */
  744. {
  745.   register int    i;
  746.  
  747.   KMDPrint("The following %d traces are available:\n", nextHead);
  748.  
  749.   for (i=0; i < nextHead; i+=4)
  750.     KMDPrint(" %s%-18.18s %s%-18s %s%-18s %s%-18s\n",
  751.          THeads[i].first ? "*" : " ", THeads[i].name,
  752.          ((i+1) < nextHead) ? THeads[i+1].first ? "*" : " " : " ",
  753.          ((i+1) < nextHead) ? THeads[i+1].name : " ",
  754.          ((i+2) < nextHead) ? THeads[i+2].first ? "*" : " " : " ",
  755.          ((i+2) < nextHead) ? THeads[i+2].name : " ",
  756.          ((i+3) < nextHead) ? THeads[i+3].first ? "*" : " " : " ",
  757.          ((i+3) < nextHead) ? THeads[i+3].name : " ");
  758. }
  759.  
  760.  
  761. /* Snapshot */
  762. static void Variables()
  763. /* Print the vars available in list - besides the nlist stuff */
  764. {
  765.   register int        i;
  766.     
  767.   KMDPrint("Variable addr.  Value                    Name\n");
  768.   for (i=0; i < nextVar; i++)
  769.     KMDPrint("  0x%08x  %10d (0x%08x)    %s\n", Vars[i].addr,
  770.          *(Vars[i].addr), *(Vars[i].addr), Vars[i].name);
  771. }
  772.  
  773.  
  774. /* Snapshot */
  775. static void Flush()
  776. /* Flushes standard error and standard output files */
  777. {
  778. #ifndef xkernel
  779.   KMDPrint("Flushing kernel stderr and stdout\n");
  780.   (void) fflush(stderr);
  781.   (void) fflush(stdout);
  782. #endif
  783. }
  784.  
  785.  
  786. /*Snapshot*/
  787. static void Menu()
  788. /* Print snaps and traces */
  789. {
  790.   Snapshots(); Traces();
  791.   KMDPrint("To print variables, try the Variables snapshot\n");
  792. }
  793.  
  794. /* Snapshot */
  795. static void Help()
  796. /* Prints out a help message */
  797. {
  798.   KMDPrint("KMD facilities:  try Menu for the list of snapshots.\n");
  799.   KMDPrint("snapshot -n Traces -- gives the avaliable traces\n");
  800.   KMDPrint("snapshot -n Snapshots -- gives the available snapshots\n");
  801. }
  802.  
  803. /* Snapshot */
  804. static void NOP()
  805. {
  806.   KMDPrint("NOP -- or Yes, I am alive\n");
  807. }
  808.  
  809. /************************************************/
  810. /*      E N D   O F   K M D   Defined snapshots.*/
  811. /************************************************/
  812.  
  813. void KMDStartTrace(fName, fLevel, fSrcSock, fUseStdout)
  814. char       *fName;
  815. int         fLevel, fSrcSock;
  816. int         fUseStdout;
  817. {
  818.   register int i;
  819.   int          sock;
  820.   char         buf[200];
  821.   int           useDebugger = 0;
  822.     
  823.   if ( KMDTest )
  824.     printf("Start %s tracing level %d to sock = %d\n", fName, fLevel,
  825.        fSrcSock);
  826.   if (!strcmp(fName, "*LineNumber")) {
  827.     useDebugger = TRUE;
  828.     fName++;
  829.   }
  830.  
  831.   if (fUseStdout) {
  832.     /* trace to std out */
  833.     sock = KMDSTDOUTSOCK;
  834.   } else sock = fSrcSock;
  835.  
  836.   for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
  837.   if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
  838.   if (i == nextHead) {
  839.     /* Not found, return error */
  840.     sprintf(buf, "Trace %s unknown\n", fName);
  841.     (void) KMDSend( fSrcSock, KMDCERRMSG, 0, buf);
  842.     return;
  843.   } else {
  844.     TraceElemPtr newElem;
  845.     /* Found it; Insert into linked list */
  846.     newElem = (TraceElemPtr) kmdalloc(sizeof(TraceElem));
  847.     HoldSigs();
  848.     newElem->next = THeads[i].first;
  849.     THeads[i].first = newElem;
  850.     newElem->tracesock = sock;
  851. #ifdef xkernel
  852.     newElem->debugger = useDebugger ? debugStart(newElem) : NULL;
  853. #else
  854.     newElem->debugger = NULL;
  855. #endif xkernel
  856.     newElem->level = fLevel;
  857.     ReleaseSigs();
  858.     if (KMDTest)
  859.       printf(" ... added: 0x%08x, sock = %d, level = %d\n", newElem,
  860.          newElem->tracesock, newElem->level);
  861.     KMDTraceAct++;
  862.     KMDSetFlags();
  863.     if (!strcmp(fName,"LineNumber")) {
  864.       emTracing = THeads[i].first != NULL;
  865.     }
  866.     sprintf(buf, "Started  trace %s level %d%s\n", fName,
  867.         newElem->level,
  868.         (newElem->tracesock == KMDSTDOUTSOCK) ? " to stdout":"");
  869.     if (sock != KMDSTDOUTSOCK) {
  870.       (void) KMDSend(fSrcSock, KMDCDATA, 0, buf);
  871.     } else printf("%s", buf);
  872.   }
  873. }
  874.  
  875. void KMDStopTrace(fName, fSrcSock, fUseStdout)
  876. char *fName;
  877. int   fSrcSock;
  878. int   fUseStdout;
  879. {
  880.   register int        i;
  881.   int                 sock;
  882.   char                buf[200];
  883.   if ( KMDTest )
  884.     printf("Stop %s tracing to sock = %d\n", fName, fSrcSock);
  885.   if (fUseStdout) {
  886.     /* trace to std out */
  887.     sock = KMDSTDOUTSOCK;
  888.   } else sock = fSrcSock;
  889.   for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
  890.   if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
  891.   if (i == nextHead) {
  892.     /* Not found, return error */
  893.     sprintf(buf, "Trace %s unknown\n", fName);
  894.     (void) KMDSend( fSrcSock, KMDCERRMSG, 0, buf);
  895.     return;
  896.   } else {
  897.     /* Found it; Remove it from linked list */
  898.     register TraceElemPtr    p, q, theEntry;
  899.  
  900.     if ( KMDTest )
  901.       printf(" ... looking for entry = %d\n", sock);
  902.  
  903.     for (p = THeads[i].first, q = NULL; p != NULL; ) {
  904.       if (KMDTest)
  905.     printf(" ... checking p = 0x%08x, q = 0x%08x, sock = %d\n",
  906.            p, q, p->tracesock);
  907.       if (p->tracesock != sock ) {
  908.     q = p; p = p->next;
  909.     continue;
  910.       };
  911.       if (KMDTest)
  912.     printf("Removing theEntry, sock = %d\n", p->tracesock);
  913.       theEntry = p;
  914.       HoldSigs();
  915.       if (q == NULL) { /* First entry */
  916.     p = p->next;
  917.     THeads[i].first = p;
  918.       } else { /* Down the line entry */
  919.     p = q->next = p->next;
  920.       };
  921.       ReleaseSigs();
  922.       if (KMDTest) printf(" ... stop tracing to sock %d\n",
  923.               theEntry->tracesock);
  924.       if (theEntry->tracesock != NULLSOCK) {
  925.     sprintf(buf, "Stopped  trace %s level %d%s\n", fName,
  926.         theEntry->level,
  927.         (theEntry->tracesock == KMDSTDOUTSOCK) ? " to stdout":"");
  928.     if (sock != KMDSTDOUTSOCK) {
  929.       (void) KMDSend(fSrcSock, KMDCDATA, 0, buf);
  930.     } else printf("%s", buf);
  931.       };
  932.       kmdfree(theEntry);
  933.       KMDTraceAct--;
  934.       KMDSetFlags();
  935.     };
  936.     if (!strcmp(fName,"LineNumber")) {
  937.       emTracing = THeads[i].first != NULL;
  938.     }
  939.   }
  940. }
  941.  
  942.  
  943. void KMDPrepareTrace(fName, fLevel)
  944. char *fName;
  945. int   fLevel;
  946. {
  947.   register int i;
  948.     
  949.   for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
  950.   if (i == nextHead) {
  951.     /* Did not find it, so retain it for later (see KMDSetTrace) */
  952.     if (nextPrepared == 0) {
  953.       CreateArray((int **)&PreparedTraces, sizeof(TraceElem));
  954.     }
  955.     EnsureArray((int **)&PreparedTraces,
  956.       (nextPrepared+1) * sizeof(PreparedElem),
  957.       (nextPrepared + 2) * sizeof(PreparedElem));
  958.  
  959.     PreparedTraces[nextPrepared].level = fLevel;
  960.     if(PreparedTraces[nextPrepared].name = kmdalloc(strlen(fName)+1))
  961.       (void) strcpy(PreparedTraces[nextPrepared].name, fName);
  962.     nextPrepared++;
  963.     return;
  964.   }
  965.   /* Found it, so start it right away */
  966.   KMDStartTrace(fName, fLevel, KMDSTDOUTSOCK, TRUE);
  967. }
  968.  
  969. /* KMDMsgHandler
  970.  *
  971.  * Invoked from task queue when there is data to read on the socket.
  972.  * Accepts requests for new KMD connections and reads specific
  973.  * requests off of old ones.
  974.  */
  975.  
  976. HResult KMDMsgHandler(fSock)
  977. int fSock;
  978. {
  979.   int          MType, MInt;
  980.   int          SrcSock;
  981.   register int i;
  982.   int         *ptr;
  983.   char         MString[MAXMESSAGESIZE];
  984.   char         snapName[MAXMESSAGESIZE];
  985.   char        *snapString;
  986.   KKStatus     status;
  987.   SnapElement  tempSnapElement;
  988. #ifdef xkernel
  989.   EMSTREAM *ems = (EMSTREAM *)fSock;
  990. #else
  991.   int nreadablebytes, newReqSock, s, sockIndex;
  992.   int          somethingHappened = 1;
  993. #endif
  994.  
  995. #ifndef xkernel
  996.   while(somethingHappened) {
  997.     somethingHappened = 0;
  998.     if (KMDTest) (void) fflush(stdout);
  999.     if (KMDTest) printf("KMDMsgHandler top of loop\n");
  1000.  
  1001.     if (fSock == KMDRequestSock) {
  1002.     reqSrcLength = sizeof(reqSrc);
  1003.     newReqSock = accept(KMDRequestSock, (struct sockaddr *) &reqSrc,
  1004.         &reqSrcLength);
  1005.     if (newReqSock < 0) {
  1006.         if (KMDTest) printf("No new request\n");
  1007.     } else {
  1008.             somethingHappened = 1;
  1009.         /* Accept and set up a new request */
  1010.         if (KMDTest) printf("New request fd %d\n", newReqSock);
  1011.         /* First, clean out the socket */
  1012.         KMDCleanSock(newReqSock);
  1013.     
  1014.         /* Second, tell the new socket that it has been connected */
  1015.         KMDShip(newReqSock, "KMD Connected to host %d\n", GetLNN());
  1016.     
  1017.         /* Third, make the request line use SIGIO */
  1018.         if (fcntl(newReqSock, F_SETFL, FASYNC) < 0 ) {
  1019.         perror("newReqSock: fcntl");
  1020.         return;
  1021.         };
  1022.     
  1023.         if (fcntl(newReqSock, F_SETOWN, getpid()) < 0 ) {
  1024.         perror("newReqSock: fcntl");
  1025.         return;
  1026.         };
  1027.  
  1028.         SISetSockHandler(newReqSock, SIREAD, (SIHandlerPtr)SIGIOOccurred);
  1029.             SISetSockHandler(newReqSock, SIEXCEPT,(SIHandlerPtr) KMDCleanSock);
  1030.             /* Ensure that a new SIGIO occurs soon (there might already be
  1031.                input on the socket) */
  1032.             SIEnsureSIGIO();
  1033.  
  1034.         /* Put into request list and sooner or later something will
  1035.            arrive (or the connection will die).
  1036.          */
  1037.             
  1038.         if (nextReq >= MAXREQSOCKS) {
  1039.         (void) KMDSend(newReqSock, KMDCERRMSG, 0,
  1040.             "Out of KMD sockets.\n");
  1041.         (void) shutdown(newReqSock, 2);
  1042.         (void) close(newReqSock);
  1043.         return;
  1044.         };
  1045.         ReqSocks[nextReq++] = newReqSock;
  1046.     };
  1047.         continue;
  1048.       }
  1049.     
  1050.     /* Now try to see if a message has arrived on any of the
  1051.        Request sockets.
  1052.      */
  1053.  
  1054.     for (sockIndex = 0; sockIndex < nextReq ; sockIndex++) {
  1055.     if ( (s = ReqSocks[sockIndex]) <= NULLSOCK ) continue;
  1056.         if (s != fSock) continue;
  1057. #ifdef ORIGINAL
  1058.     if (fcntl(s, F_SETFL, FASYNC | FNDELAY) < 0 ) {
  1059.         perror("KMDRead: fcntl");
  1060.         continue;
  1061.     };
  1062.     status = KMDReceive(s, &MType, &MInt, MString);
  1063.     if (fcntl(s, F_SETFL, FASYNC) < 0 ) {
  1064.         perror("KMDMsgHandler: fcntl");
  1065.         continue;
  1066.     };
  1067.         if (!mSUCCESS(status)) {
  1068.         if (errno == EWOULDBLOCK) continue;
  1069.         /* Bad error */
  1070.             perror("KMD: socket recv error");
  1071.         KMDCleanSock(s);
  1072.             continue;
  1073.     };
  1074. #else
  1075.     if (ioctl(s, FIONREAD, &nreadablebytes) < 0) {
  1076.         perror("KMDRead: iocntl");
  1077.         continue;
  1078.     }
  1079.     if (nreadablebytes <= 0) continue;
  1080.     status = KMDReceive(s, &MType, &MInt, MString);          
  1081.         if (!mSUCCESS(status)) {
  1082.         /* Bad error */
  1083.             perror("KMD: socket recv error");
  1084.         KMDCleanSock(s);
  1085.             continue;
  1086.     };
  1087. #endif
  1088. #else xkernel
  1089.     status = KMDReceive((int)ems, &MType, &MInt, MString);          
  1090.     if (!mSUCCESS(status)) {    /* Bad error.  who cares */
  1091.       if (KMDTest) printf("KMDReceive failed in kmdmsghandler!\n");
  1092.       KMDCleanSock((int)ems);
  1093.       return;
  1094.     }
  1095.     if (KMDTest) printf("In KMDMsgHandler, KMDreceived message type %d\n",MType);
  1096. #endif xkernel
  1097.  
  1098.  
  1099.     /* Now start decoding the request: */
  1100. #ifndef xkernel
  1101.     somethingHappened = 1;
  1102. #endif
  1103.     if (KMDTest) {
  1104.       printf("KMDMsgHandler: Type = %d, Int = %d, string = %d\n",
  1105.          MType, MInt, MString);
  1106.     }
  1107.  
  1108. #ifdef xkernel
  1109.     SrcSock = (int)ems;
  1110. #else
  1111.     SrcSock = s;
  1112. #endif
  1113.     switch ( MType ) {
  1114.  
  1115.     case KMDCTRACE:         /* Start trace message */
  1116.         KMDStartTrace(MString, MInt, SrcSock, FALSE);
  1117.     endcase;
  1118.  
  1119.     case KMDCUNTRACE:       /* Untrace message */
  1120.         KMDStopTrace(MString, SrcSock, FALSE);
  1121.     endcase;
  1122.  
  1123.     case KMDCTRACESTDOUT:   /* Start trace message */
  1124.         KMDStartTrace(MString, MInt, SrcSock, TRUE);
  1125.     endcase;
  1126.  
  1127.     case KMDCUNTRACESTDOUT: /* Untrace message */
  1128.         KMDStopTrace(MString, SrcSock, TRUE);
  1129.     endcase;
  1130.     
  1131.     case KMDCSNAPSHOT:          /* Do a snapshot */
  1132.         if (KMDTest) printf("Starting snapshot.\n");
  1133.         if(sscanf(MString, "%s", snapName) != 1) {
  1134.         (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "bad snapshot name\n");
  1135. #ifdef xkernel
  1136.         return;
  1137. #else
  1138.         continue;
  1139. #endif
  1140.     };
  1141.     for (i=0; MString[i] != ' '; i++);
  1142.     snapString = &MString[i+1];
  1143.         for (i=0; i < nextSnap ? strcmp(snapName, Snaps[i].name) : 0; i++);
  1144.         if (KMDTest) printf(" ... i = %d, nextSnap = %d\n", i, nextSnap);
  1145.         if (i == nextSnap) {
  1146.             /* Not found: Return error */
  1147.             (void) KMDSend(SrcSock, KMDCERRMSG, 0, "Unknown snapshot.\n");
  1148. #ifdef xkernel
  1149.         return;
  1150. #else
  1151.         continue;
  1152. #endif
  1153.         }
  1154.         /* Improve performance by using move-to-front for linear list */
  1155.         tempSnapElement = Snaps[0];
  1156.         Snaps[0] = Snaps[i];
  1157.         Snaps[i] = tempSnapElement;
  1158.         if (KMDTest) printf(" ... Snapshot sock = %d \n", SrcSock);
  1159.         KMDSnapSock = SrcSock;
  1160.         
  1161.         (*Snaps[0].handler) (MInt, snapString);
  1162.  
  1163.         (void) KMDSend(KMDSnapSock, KMDCLASTMSG, 0,
  1164.         "*** End of Snapshot ***\n");
  1165.         KMDSnapSock = NULLSOCK;
  1166.     KMDSetFlags();
  1167.     endcase;
  1168.  
  1169.     case KMDCPRINTVAR:          /* Print Variable */
  1170.         if ( KMDTest ) printf("Printing variable\n");
  1171.         ptr = VarLookup(MString);
  1172.         if (ptr == (int *) -1) {
  1173.             /* Not found, return error */
  1174.             (void) KMDSend(SrcSock, KMDCERRMSG, 0,
  1175.         "Variable name not found.\n");
  1176. #ifdef xkernel
  1177.         return;
  1178. #else
  1179.         continue;
  1180. #endif
  1181.         };
  1182.         KMDShip(SrcSock, "%s = %d (0x%08x)\n",  MString, *ptr, *ptr);
  1183.         (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "** Done **\n");
  1184.     endcase;
  1185.  
  1186.     case KMDCCHANGEVAR:     /* Change value of integer variable */
  1187.         if ( KMDTest ) printf("Change variable.\n");
  1188.         ptr = VarLookup(MString);
  1189.         if (ptr == (int *) -1) {
  1190.             /* Not found, return error */
  1191.             (void) KMDSend(SrcSock, KMDCERRMSG, 0,
  1192.         "Variable name not found.\n");
  1193. #ifdef xkernel
  1194.         return;
  1195. #else
  1196.         continue;
  1197. #endif
  1198.         };
  1199.         *ptr = MInt;
  1200.         KMDShip(SrcSock, "%s @ 0x%08x changed to %d (0x%08x)\n", 
  1201.             MString, ptr, *ptr, *ptr);
  1202.         (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "** Done **\n");
  1203.         KMDSetFlags();
  1204.     endcase;
  1205.     
  1206.     case KMDCLASTMSG:          /* Last message */
  1207.     KMDCleanSock(SrcSock);
  1208. #ifdef BSD
  1209.         (void) shutdown(SrcSock, 2);  /* Close down connection */
  1210.         (void) close(SrcSock);
  1211. #else
  1212. #ifdef xkernel
  1213.     {
  1214.       int x;
  1215.       x = spl7();
  1216.       if(!ems->eof) {
  1217.         ems_close(ems);
  1218.       }
  1219.       splx(x);
  1220.     }
  1221. #endif
  1222. #endif
  1223.     /* Deallocate request */
  1224.         if (KMDTest) printf("Closing connection to %d\n", SrcSock);
  1225. #ifdef CLOSEITSOMEHOW
  1226. #ifndef xkernel
  1227.     if (KMDTest) printf("Closing connection to %d\n", SrcSock);
  1228.         (void) shutdown(SrcSock, 2);  /* Close down connection */
  1229.         (void) close(SrcSock);
  1230.     /* Deallocate request */
  1231.     if (i < --nextReq) {
  1232.         ReqSocks[i] = ReqSocks[nextReq];
  1233.     };
  1234. #else xkernel
  1235.     if (KMDTest) printf("Closing connection to %d\n", SrcSock);
  1236.     xclose(((EMSTREAM *)SrcSock)->sessn);
  1237.     (EMSTREAM *)SrcSock->sessn = 0;
  1238. #endif
  1239. #endif CLOSEITSOMEHOW
  1240.     endcase;
  1241.  
  1242. #ifdef NOTIMPLEMENTED
  1243.     case KMDCGETBYTES:         /* Send back a sequence of bytes */
  1244.     MBytes = (long *) MString;
  1245.     bufptr = bytebuf;
  1246.     if (KMDTest)
  1247.         printf("GetBytes: count = %d, data: (0x%08x %d) (0x%08x %d)\n",
  1248.             MBytes[0], MBytes[1], MBytes[2], MBytes[3], MBytes[4]);
  1249.         for (i=0; i < MBytes[0] ; i++) {
  1250.         /* Get a contigous set of bytes */
  1251.         from =  (char *) (MBytes[2*i+1]);
  1252.         size = MBytes[2*i+2];
  1253.         bcopy(from, bufptr, size);
  1254.         bufptr = bufptr+size;
  1255.     };
  1256.     size = bufptr - bytebuf;
  1257.     (void) KMDSendBlock(NULLSOCK, SrcSock, KMDCBYTES, size, bytebuf,
  1258.         NORMALMSG);
  1259.     endcase;
  1260. #endif NOTIMPLEMENTED
  1261.  
  1262.     default:
  1263.         if (KMDTest) 
  1264.       printf("**** KMD: Bad type in incoming KMD msg: %d, int=%d\n",
  1265.           MType, MInt);
  1266.         (void) KMDSend(SrcSock, KMDCERRMSG, 0,
  1267.         "**** Bad KMD msg type ****\n");
  1268.     };
  1269. #ifndef xkernel
  1270.     if (KMDTest) (void) fflush(stdout);
  1271. #endif
  1272. #ifndef xkernel
  1273.       }
  1274.   }
  1275. #endif
  1276. }
  1277.  
  1278. /*
  1279.  *
  1280.  * KMDCleanSock
  1281.  *
  1282.  * Cleans a KMD sock, i.e., removes any traces being sent
  1283.  * to the sock.
  1284.  */
  1285. void KMDCleanSock( fSock )
  1286. int fSock;
  1287. {
  1288.   register int i;
  1289.   register TraceElemPtr p, q;
  1290.  
  1291.   if (KMDTest) printf("KMDCleanSock %d\n", fSock);
  1292. #ifndef xkernel
  1293.   /* Traverse the list of traces and remove any that point to the dead sock.*/
  1294.   for (i = 0; i < nextReq ; i++) {
  1295.     /* Clean out the request socket data structure */
  1296.     if ((fSock == ReqSocks[i]) || (ReqSocks[i] == NULLSOCK)) {
  1297.       /* Remove from request list */
  1298.       SIRemoveSockHandler(fSock, SIREAD);
  1299.       SIRemoveSockHandler(fSock, SIWRITE);
  1300.       SIRemoveSockHandler(fSock, SIEXCEPT);
  1301.       if (i < --nextReq) {
  1302.     if (KMDTest) printf("Removing ReqSock[%d] == %d \n", i, ReqSocks[i]);
  1303.     ReqSocks[i] = ReqSocks[nextReq];
  1304.     /* Now decrement i since the structure has been compacted */
  1305.     i--;
  1306.       };
  1307.     }
  1308.   }
  1309. #endif
  1310.   /* Clean up the trace data structure */
  1311.   for (i=0; i < nextHead ; i++) {
  1312.     if (KMDTest) printf(" ... i = %d, name = %s, nextHead = %d\n", i,
  1313.             THeads[i].name, nextHead);
  1314.     for (p = THeads[i].first, q = NULL; p != NULL; ) {
  1315.       if (KMDTest)
  1316.     printf(" ... q = 0x%08x, p = 0x%08x, sock = %d, level = %d\n",
  1317.            q, p, p->tracesock, p->level);
  1318.  
  1319.       if ((p->tracesock != fSock) && (p->tracesock != NULLSOCK) ){
  1320.     /* Sock ok, advance pointer */
  1321.     q=p; p = p->next;
  1322.       } else {
  1323.     /* The sock has died:  remove the trace entry */
  1324.     TraceElemPtr    BumEntry = p;
  1325.     if ( KMDTest )
  1326.       printf(" .. Dead Sock cleaning = %d\n", p->tracesock);
  1327.     HoldSigs();
  1328.     if (q == NULL) { /* First entry */
  1329.       p = p->next;
  1330.       THeads[i].first = p;
  1331.     } else { /* Down the line entry */
  1332.       p = q->next = p->next; 
  1333.     };
  1334.     ReleaseSigs();
  1335.     if (!strcmp(THeads[i].name, "LineNumber")) {
  1336.       emTracing = THeads[i].first != NULL;
  1337.     }
  1338. #ifdef xkernel
  1339.     if (BumEntry->debugger) debugEnd(BumEntry);
  1340. #endif xkernel
  1341.     if (BumEntry->tracesock != NULLSOCK){
  1342. #ifdef BSD
  1343.       (void) close(BumEntry->tracesock); /* ignore result */
  1344. #else
  1345. #ifdef xkernel
  1346.       ems_close((EMSTREAM *)BumEntry->tracesock); /* ignore result */
  1347. #endif xkernel
  1348. #endif
  1349.     }
  1350.     kmdfree(BumEntry);
  1351.     KMDTraceAct--;
  1352.     KMDSetFlags();
  1353.       }
  1354.     }
  1355.   }
  1356. }
  1357.  
  1358.  
  1359.  
  1360. /*
  1361.  *
  1362.  * PrintVar
  1363.  *
  1364.  * Print out a given variable
  1365.  *
  1366.  */
  1367. /* Snapshot */
  1368. /*ARGSUSED*/
  1369. void PrintVar(fInt, fString)
  1370. int fInt;
  1371. char *fString;
  1372. {
  1373.   int *ptr;
  1374.     
  1375.   if ( KMDTest ) printf("Printing variable\n");
  1376.   ptr = VarLookup(fString);
  1377.   if (ptr == (int *) -1) {
  1378.     /* Not found, return error */
  1379.     KMDPrint("Variable name %s not found.\n", fString);
  1380.     return;
  1381.   }
  1382.   KMDPrint("%s = %d (0x%08x)\n",  fString, *ptr, *ptr);
  1383. }
  1384.  
  1385. /*
  1386.  *
  1387.  * ChangeVar
  1388.  *
  1389.  * Snapshot to give an integer variable a new value
  1390.  *
  1391.  */
  1392. /* Snapshot */
  1393. void ChangeVar(fInt, fString)
  1394. int             fInt;
  1395. char           *fString;
  1396. {
  1397.   int *ptr;
  1398.     
  1399.   if ( KMDTest ) printf("Change variable %s to %d .\n", fString, fInt);
  1400.   ptr = VarLookup(fString);
  1401.   if (ptr == (int *) -1) {
  1402.     /* Not found, return error */
  1403.     KMDPrint("Variable name %s not found.\n", fString);
  1404.     return;
  1405.   }
  1406.   *ptr = fInt;
  1407.   KMDPrint("%s @ 0x%08x changed to %d (0x%08x)\n", fString, ptr, *ptr, *ptr);
  1408.   KMDSetFlags();
  1409. }
  1410.  
  1411.  
  1412. /*
  1413.  *
  1414.  * KMDInit
  1415.  *
  1416.  * KMDInit initializes the KMD part of the Eden kernel
  1417.  * resident part.
  1418.  *
  1419.  */
  1420. void KMDInit(fKMDSockNumber)
  1421. unsigned short fKMDSockNumber; /* in network byte order */
  1422. {
  1423.   DebugMsg(5, "KMDInit, KMD port = %d\n", ntohs(fKMDSockNumber));
  1424.  
  1425. #ifdef BSD
  1426.   KMDRequestSock = socket(AF_INET, SOCK_STREAM, 0);
  1427.   if (KMDRequestSock < 0) {
  1428.     perror("KMDInit: socket");
  1429.     return;
  1430.   }
  1431.   mySocket.sin_port = fKMDSockNumber;
  1432.   if (bind(KMDRequestSock, &mySocket, sizeof(mySocket)) < 0) {
  1433.     perror("KMDInit: bind(KMDRequestSock)");
  1434.     /* Fatal error so cause a fatal fault */
  1435.     * ((int *) 0) = 0;
  1436.   }
  1437.  
  1438.   if (fcntl(KMDRequestSock, F_SETFL, FASYNC | FNDELAY ) < 0) {
  1439.     perror("KMDInit: first fcntl");
  1440.   }
  1441.   if (fcntl(KMDRequestSock, F_SETOWN, getpid()) < 0) {
  1442.     perror("KMDInit: second fcntl");
  1443.   }
  1444.  
  1445.   check(listen(KMDRequestSock, 5));
  1446.  
  1447.   SISetSockHandler(KMDRequestSock, SIREAD, (SIHandlerPtr) SIGIOOccurred);
  1448.   SISetSockHandler(KMDRequestSock, SIEXCEPT, (SIHandlerPtr) KMDCleanSock);
  1449. #else BSD
  1450. #ifdef xkernel
  1451.   xcontrolprotl(IP,0,(char *)&myipaddr,IPADLEN);
  1452.   if((KMDProtl = xcreateprotl(KMDdemux_handler, KMDopendone_handler,
  1453.                    KMDclosedone_handler)) == -1){
  1454.     printf("Can't create KMDProtl in kmdCode.c!\n");
  1455.     abort();
  1456.   }
  1457.   {
  1458.     PART part[2];
  1459.     TCPaddr me;
  1460.  
  1461.     me.port = fKMDSockNumber; me.host = myipaddr;
  1462.     part[0].address = (char *)&me; part[0].length = TCPADLEN;
  1463.     part[1].address = NULL; part[1].length = 0;
  1464.     if(xopenenable(KMDProtl, TCP, part) == -1){
  1465.       printf("Can't openenable TCP in kmdCode.c!\n");
  1466.       abort();
  1467.     }
  1468.   }
  1469. #endif xkernel
  1470. #endif BSD
  1471.  
  1472.     /* Define standard traces */
  1473. #undef DebugMsg
  1474.     KMDSetTrace(DebugMsg);
  1475.     KMDSetTrace(MMTraceMsg);
  1476.     
  1477.     /* Define KMD snapshots available in this source file */
  1478.     KMDSetSnap(Menu);
  1479.     KMDSetSnap(Snapshots);
  1480.     KMDSetSnap(Traces);
  1481.     KMDSetSnap(Variables);
  1482.     KMDSetSnap(Flush);
  1483.     KMDSetSnap(Help);
  1484.     KMDSetSnap(NOP);
  1485.     KMDSetSnap(PrintVar);
  1486.     KMDSetSnap(ChangeVar);
  1487.  
  1488.     /* Define a few vars for testing */
  1489.     KMDSetVar(DebugLevel);
  1490.     KMDSetVar(MMTrace);
  1491.  
  1492.     /* Local vars in this file */
  1493.     KMDSetVar(KMDTraceAct);
  1494.     KMDSetVar(KMDTest);
  1495. }
  1496.